package com.studerb.dao;

import java.util.List;

import org.hibernate.Query;
import org.springframework.stereotype.Repository;

import com.studerb.dao.interfaces.IHeaderDao;
import com.studerb.model.Header;
import com.studerb.model.NewsGroup;

@Repository public class HeaderDao extends HibSpringDaoImp<Header> implements IHeaderDao {

	@Override public int deleteByNewsGroup(NewsGroup newsGroup, Long min, Long max) {
		String queryString;
		Query query = null;
		if (min == null && max == null) {
			queryString = "delete from Header h where h.newsGroup.id = :id";
			query = getCurrentSession().createQuery(queryString);
		}
		else if (min == null) {
			queryString = "delete from Header h where h.newsGroup.id = :id and h.articleNumber <= :max";
			query = getCurrentSession().createQuery(queryString).setParameter("max", max);
		}
		else if (max == null) {
			queryString = "delete from Header h where h.newsGroup.id = :id and h.articleNumber >= :min";
			query = getCurrentSession().createQuery(queryString).setParameter("min", min);
		}
		else {
			queryString = "delete from Header h where h.newsGroup.id = :id and h.articleNumber between :min AND :max";
			query = getCurrentSession().createQuery(queryString).setParameter("min", min).setParameter("max", max);
		}
		query.setParameter("id", newsGroup.getId());
		int deleted = query.executeUpdate();
		logger.debug("Deleted " + deleted + " headers from newsgroup: " + newsGroup.getGroupName() + "between min / max: " + min + " / " + max);
		return deleted;
	}

	private List<Header> getAllByNewsGroup(NewsGroup newsGroup) {
		logger.debug("Fetching all headers for newsgroup: " + newsGroup.getGroupName());
		String queryString = "from Header h where h.newsGroup.id = :id order by articleNumber";
		Query query = getCurrentSession().createQuery(queryString).setLong("id", newsGroup.getId());
		List<Header> headers = query.list();
		for (Header h : headers) {
			h.setNewsGroup(newsGroup);
		}
		return headers;
	}

	@Override public List<Header> getAllByNewsGroup(NewsGroup newsGroup, Long begin, Long end) {
		Query q;
		if (begin == null && end == null) {
			return getAllByNewsGroup(newsGroup);
		}
		else if (begin == null) {
			q = getCurrentSession().createQuery("from Header h where h.articleNumber <= :end AND h.newsGroup.id = :newsGroupId order by h.articleNumber asc");
			q.setLong("end", end);
		}
		else if (end == null) {
			q = getCurrentSession().createQuery("from Header h where h.articleNumber >= :begin AND h.newsGroup.id = :newsGroupId order by h.articleNumber asc");
			q.setLong("begin", begin);
		}
		else {
			q = getCurrentSession().createQuery("from Header h where h.articleNumber between :begin AND :end AND h.newsGroup.id = :newsGroupId order by h.articleNumber asc");
			q.setLong("begin", begin);
			q.setLong("end", end);
		}
		q.setLong("newsGroupId", newsGroup.getId());
		List<Header> headers = q.list();
		String msg = String.format("Obtained %d headers from group: %s between %d AND %d inclusive.", headers.size(), newsGroup.getGroupName(), begin, end);
		logger.debug(msg);
		return headers;
	}

	@Override public List<Header> getAllSinglePart(NewsGroup newsGroup, Long min, Long max) {
		String queryString;
		Query q;
		if (min == null && max == null) {
			queryString = "from Header h where h.headerThread is null AND h.newsGroup.id = :id";
			q = getCurrentSession().createQuery(queryString);
		}
		else if (min == null) {
			queryString = "from Header h where h.headerThread is null AND h.articleNumber <= :max AND h.newsGroup.id = :id order by h.articleNumber";
			q = getCurrentSession().createQuery(queryString).setParameter("max", max);
		}
		else if (max == null) {
			queryString = "from Header h where h.headerThread is null AND h.articleNumber >= :min AND h.newsGroup.id = :id order by h.articleNumber";
			q = getCurrentSession().createQuery(queryString).setParameter("min", min);
		}
		else {
			queryString = "from Header h where h.headerThread is null AND h.articleNumber between :min AND :max AND h.newsGroup.id = :id order by h.articleNumber";
			q = getCurrentSession().createQuery(queryString).setParameter("min", min).setParameter("max", max);
		}
		q.setParameter("id", newsGroup.getId());
		List<Header> headers = q.list();
		logger.debug("Getting all single part (" + headers.size() + ") for group: " + newsGroup.getGroupName());
		return headers;
	}

	@Override public void saveHeaders(List<Header> headers, NewsGroup newsGroup) {
		batchInsert(headers);
		logger.debug("Saved: " + headers.size() + " headers for group: " + newsGroup.getGroupName());
	}
}
